package bma.common.langutil.ai.objectpool;

public abstract class BaseAIKeyedObjectPool<KTYPE, VTYPE> implements
		AIKeyedObjectPool<KTYPE, VTYPE> {

	/**
	 * <p>
	 * Invalidates an object from the pool.
	 * </p>
	 * 
	 * <p>
	 * By contract, <code>obj</code> <strong>must</strong> have been obtained
	 * using {@link #borrowObject borrowObject} using a <code>key</code> that is
	 * equivalent to the one used to borrow the <code>Object</code> in the first
	 * place.
	 * </p>
	 * 
	 * <p>
	 * This method should be used when an object that has been borrowed is
	 * determined (due to an exception or other problem) to be invalid.
	 * </p>
	 * 
	 * @param key
	 *            the key used to obtain the object
	 * @param obj
	 *            a {@link #borrowObject borrowed} instance to be returned.
	 * @throws Exception
	 */
	public abstract void invalidateObject(KTYPE key, VTYPE obj) throws Exception;

	/**
	 * Not supported in this base implementation. Always throws an
	 * {@link UnsupportedOperationException}, subclasses should override this
	 * behavior.
	 * 
	 * @param key
	 *            ignored
	 * @throws UnsupportedOperationException
	 */
	public void addObject(KTYPE key) throws Exception,
			UnsupportedOperationException {
		throw new UnsupportedOperationException();
	}

	/**
	 * Not supported in this base implementation.
	 * 
	 * @return a negative value.
	 * @param key
	 *            ignored
	 */
	public int getNumIdle(KTYPE key) throws UnsupportedOperationException {
		return -1;
	}

	/**
	 * Not supported in this base implementation.
	 * 
	 * @return a negative value.
	 * @param key
	 *            ignored
	 */
	public int getNumActive(KTYPE key) throws UnsupportedOperationException {
		return -1;
	}

	/**
	 * Not supported in this base implementation.
	 * 
	 * @return a negative value.
	 */
	public int getNumIdle() throws UnsupportedOperationException {
		return -1;
	}

	/**
	 * Not supported in this base implementation.
	 * 
	 * @return a negative value.
	 */
	public int getNumActive() throws UnsupportedOperationException {
		return -1;
	}

	/**
	 * Not supported in this base implementation.
	 * 
	 * @throws UnsupportedOperationException
	 */
	public void clear() throws Exception, UnsupportedOperationException {
		throw new UnsupportedOperationException();
	}

	/**
	 * Not supported in this base implementation.
	 * 
	 * @param key
	 *            ignored
	 * @throws UnsupportedOperationException
	 */
	public void clear(KTYPE key) throws Exception, UnsupportedOperationException {
		throw new UnsupportedOperationException();
	}

	/**
	 * Close this pool. This affects the behavior of <code>isClosed</code> and
	 * <code>assertOpen</code>.
	 */
	public void close() throws Exception {
		closed = true;
	}

	/**
	 * Has this pool instance been closed.
	 * 
	 * @return <code>true</code> when this pool has been closed.
	 * @since Pool 1.4
	 */
	protected final boolean isClosed() {
		return closed;
	}

	/**
	 * Throws an <code>IllegalStateException</code> when this pool has been
	 * closed.
	 * 
	 * @throws IllegalStateException
	 *             when this pool has been closed.
	 * @see #isClosed()
	 * @since Pool 1.4
	 */
	protected final void assertOpen() throws IllegalStateException {
		if (isClosed()) {
			throw new IllegalStateException("Pool not open");
		}
	}

	/** Whether or not the pool is close */
	private volatile boolean closed = false;
}
